package com.task.controller.annotation.impl;

import com.task.controller.annotation.UseControl;
import com.task.controller.control.Control;
import com.task.controller.control.impl.DefaultControl;
import com.task.controller.util.ReflectionsUtil;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.StringJoiner;

public class UseControlImpl {

    private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.INFO, 0, UseControlImpl.class.getName());

    public static Control initControl(Context context) {
        Set<Class<?>> classes = ReflectionsUtil.getClassByAnnotationClass(UseControl.class);
        if (classes != null && classes.size() > 1) {
            StringJoiner stringJoiner = new StringJoiner("\n");
            for (Class<?> aClass : classes) {
                stringJoiner.add(String.valueOf(aClass));
            }
            throw new IllegalStateException("默认调度器过多：".concat(stringJoiner.toString()));
        } else if (classes == null || classes.size() < 1) {
            HiLog.info(LABEL_LOG, "将使用默认调度器：".concat(DefaultControl.class.getCanonicalName()));
            Control control = DefaultControl.getInstance();
            control.initControl(context);
            return control;
        } else {
            Class<?> aClass = classes.iterator().next();
            Method[] methods = aClass.getDeclaredMethods();
            for (Method method : methods) {
                UseControl useControl = method.getDeclaredAnnotation(UseControl.class);
                if (useControl == null) {
                    continue;
                }
                method.setAccessible(true);
                Class<?>[] types = method.getParameterTypes();
                if (types.length == 0) {
                    try {
                        Control control = (Control) method.invoke(null);
                        control.initControl(context);
                        return control;
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                } else if (types[0].isInstance(context)) {
                    try {
                        Control control = (Control) method.invoke(null, context);
                        control.initControl(context);
                        return control;
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                } else {
                    throw new IllegalStateException("没有合适的对象获取方法，请提供无参方法或者参数仅为：".concat(Context.class.getCanonicalName()).concat("的静态方法"));
                }
            }
            Constructor<?>[] constructors = aClass.getDeclaredConstructors();
            for (Constructor<?> constructor : constructors) {
                Class<?>[] parameterTypes = constructor.getParameterTypes();
                if (parameterTypes.length == 0) {
                    constructor.setAccessible(true);
                    try {
                        Control control = (Control) constructor.newInstance();
                        control.initControl(context);
                        return control;
                    } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                } else if (parameterTypes[0].isInstance(context)) {

                    try {
                        Control control = (Control) constructor.newInstance(context);
                        control.initControl(context);
                        return control;
                    } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                } else {
                    throw new IllegalStateException("默认调度器没有合适的构造方法，若没有静态的对象获取方法，则必须有至少一个构造方法是无参构造或者是参数仅为：".concat(Context.class.getCanonicalName()).concat("的构造方法"));
                }
            }
        }
        return null;
    }
}
